#ifndef XFORMAT_H
#define XFORMAT_H
#include "xtools.h"
#include <mutex>
#include <memory>
class AVFormatContext;
class AVCodecParameters;
class AVPacket;
class AVCodecContext;
struct XRational {
  int num; ///< Numerator
  int den; ///< Denominator
};
class XFormat {
public:
  virtual ~XFormat() {}
  /// \brief CopyPara 复制参数 线程安全
  /// \param stream_index 对应流的位置，对应streams的下标
  /// \param dst 输出参数
  /// \return
  bool CopyPara(int stream_index, AVCodecParameters *dst);
  bool CopyPara(int stream_index, AVCodecContext *dst);
  /// @brief CopyVideoPara 拷贝视频参数
  /// @return 
  std::shared_ptr<XPara> CopyVideoPara();
  std::shared_ptr<XPara> CopyAudioPara();
  /////////////////////////////
  /// \brief set_c 设置封装或解封装的上下文，如果c为nullptr，相当于关闭
  /// \param c 上下文
  /// info：需要注意的是，对于封装需要提前设置好avstream的Type
  void set_c(AVFormatContext *c);

  int audio_index() { return audio_index_; }
  int video_index() { return video_index_; }

  XRational video_time_base() { return video_time_base_; }
  XRational audio_time_base() { return audio_time_base_; }
  // 根据time_base计算pkt的pts，dts，duration
  bool RescaleTime(AVPacket *pkt, long long offset_pts, AVRational* time_base);
  bool RescaleTime(AVPacket* pkt, long long offset_pts, XRational time_base);
  //
  int video_codec_id() { return video_codec_id_; }
  int audio_codec_id() { return audio_codec_id_; }
  // 判断是否超时
  bool IsTimeout() {
    if (NowMs() - last_time_ > time_out_ms_) {
      last_time_ = NowMs();
      is_connected_ = false;
      return true;
    }
    return false;
  }
  // 设置超时时间
  void set_time_out_ms(int ms);
  //
  bool is_connected() { return is_connected_; }
  //
  std::string url();

protected:
  // 超时时间 毫秒
  int time_out_ms_ = 0;
  // 上次接收数据的时间
  long long last_time_ = 0;
  // 是否连接成功，会在设置set_c成功时设置为true，失败时设置成false，并且超时也会被设为false（所以如有必要应当
  bool is_connected_ = false;
  // 封装或解封装上下文
  AVFormatContext *c_ = nullptr;
  // c_的互斥量
  std::mutex mux_;
  int audio_index_ = 1;
  int video_index_ = 0;
  XRational video_time_base_ = {1, 25};
  XRational audio_time_base_ = {1, 9000};
  int video_codec_id_ = 0;
  int audio_codec_id_ = 0;
};

#endif // XFORMAT_H
